Repository navigation
[RDMW-24943][AI-219] Added device management to the Devolutions Agent - #2194
Maxime Forest (forestmaxime) wants to merge 8 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The device management stream now opens on the Agent Identity channel URL over HTTPS. The agent signs the opening with its identity key and answers the server challenge with a proof. Removed the unauthenticated Enroll call, the device id file, the gRPC URL setting and the installer dialog. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The scripts install the latest agent for Windows (MSI) or Linux x64 (deb), check its SHA-256 hash, turn on Device Management and enroll the device with the token from DEVOLUTIONS_ENROLLMENT_TOKEN.
DEVOLUTIONS_AGENT_DEV_URL installs a locally built agent instead of the published package, and adds the test root CA and broker settings. Start-DevInstallServer.ps1 serves the builds and scripts with that URL set. The default path still installs the latest version from productinfo.json.
Let maintainers know that an action is required on their side
|
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical flaws can execute administrative requests twice, expose UniGetUI credentials, and leave broken installations when MSI uninstallation fails.
10 open issues
Avoid retrying submitted administrative requests on another endpoint · New Disable proxy discovery for local IPC requests · New Redact the authentication token from request errors · New Stop cleanup when MSI uninstall fails · New Route device management through the configured proxy · New Collect inventory without blocking the stream loop · New Wait for all enabled managers before replacing the inventory · New Skip inventory reporting when source queries fail · New Persist the catalog snapshot and revision transactionally · New Preserve device management when installing or upgrading the MSI · New
What changed in this PR
Adds a device-management prototype to Devolutions Agent, enabling RDM and Devolutions Server to manage device packages through UniGetUI.
Changes:
- Adds an Agent Identity-authenticated stream for package inventory, remote operations, and software catalog synchronization.
- Integrates configuration and service startup, supports pinned-version Winget installs, and updates TLS initialization and file permissions.
- Adds installation, enrollment, removal, and local-development scripts.
| File | Description |
|---|---|
package/install/uninstall-agent.sh |
Removes Linux packages, service, and agent data. |
package/install/uninstall-agent.ps1 |
Removes Windows installations, service, and protected data. |
package/install/Start-DevInstallServer.ps1 |
Serves local builds and customized setup scripts. |
package/install/reinstall-unigetui.ps1 |
Reinstalls UniGetUI from the development server. |
package/install/install-agent.sh |
Installs, configures, and enrolls Linux agents. |
package/install/install-agent.ps1 |
Installs and enrolls Windows agents with readiness retries. |
package/AgentWindowsManaged/Actions/CustomActions.cs |
Maps device management to the PEDM installer feature. |
devolutions-agent/src/updater/security.rs |
Protects applied file permissions from inheritance. |
devolutions-agent/src/updater/mod.rs |
Exposes the permission helper within the crate. |
devolutions-agent/src/service.rs |
Starts the enabled device-management task. |
devolutions-agent/src/main.rs |
Initializes the rustls cryptographic provider. |
devolutions-agent/src/lib.rs |
Exports the device-management module. |
devolutions-agent/src/device_management/unigetui.rs |
Implements UniGetUI discovery, inventory, and package operations. |
devolutions-agent/src/device_management/software_catalog.rs |
Applies catalog snapshots and records revisions. |
devolutions-agent/src/device_management/mod.rs |
Manages authentication, requests, and inventory reporting. |
devolutions-agent/src/config.rs |
Adds optional device-management configuration. |
devolutions-agent/proto/device_management.proto |
Defines the bidirectional device-management protocol. |
devolutions-agent/Cargo.toml |
Adds request-signing and middleware dependencies. |
devolutions-agent/build.rs |
Generates device-management protocol bindings. |
crates/now-package-broker/src/command_builder/winget.rs |
Forces version-pinned installs to support downgrades. |
Cargo.lock |
Records the agent’s added dependencies. |
Review effort: Balanced
| error = format!("{error:#}"), | ||
| "UniGetUI endpoint failed" | ||
| ); | ||
| last_error = Some(error); |
| match &endpoint.transport { | ||
| Transport::Tcp(port) => { | ||
| let url = format!("http://localhost:{port}{path_and_query}"); | ||
| let client = reqwest::Client::builder().timeout(timeout).build()?; |
| let response = request.send().await.context("UniGetUI TCP request failed")?; | ||
| let status = response.status(); | ||
| let body = response.text().await.context("failed to read UniGetUI response")?; |
| Write-Host "Removing $($product.DisplayName) $($product.DisplayVersion)..." | ||
| $exitCode = (Start-Process msiexec.exe -ArgumentList "/x $($product.PSChildName) /qn /norestart" -Wait -PassThru).ExitCode | ||
| if ($exitCode -notin 0, 1605, 3010) { | ||
| Write-Host "msiexec failed with exit code $exitCode." -ForegroundColor Yellow |
| .http2_keep_alive_interval(KEEP_ALIVE_INTERVAL) | ||
| .keep_alive_timeout(KEEP_ALIVE_TIMEOUT) | ||
| .keep_alive_while_idle(true) | ||
| .connect() |
|
|
||
| match message.payload { | ||
| Some(ServerPayload::SyncInventory(_)) => { | ||
| if let Some(report) = collect_inventory().await { |
| }; | ||
|
|
||
| // UniGetUI returns an empty list for a manager that is not ready, for example just after logon or wake. | ||
| if !managers.iter().any(|manager| manager.enabled && manager.installed) { |
| let sources = unigetui::sources().await.unwrap_or_else(|error| { | ||
| warn!( | ||
| error = format!("{error:#}"), | ||
| "Failed to collect UniGetUI package sources" | ||
| ); | ||
| Vec::new() | ||
| }); |
| catalog_sync::Content::Delete(false) => bail!("invalid software catalog delete request"), | ||
| } | ||
|
|
||
| atomic_write(&revision_path, request.revision.to_string().as_bytes())?; |
| bool pedmEnabled = enabledFeatures.Contains(Features.PEDM_FEATURE.Id.Substring(Features.FEATURE_ID_PREFIX.Length)); | ||
| return ToggleAgentFeature(session, "DeviceManagement", pedmEnabled); |


Jira Ticket
Related PRs
Description
Device Management (PEDM) prototype: RDM and DVLS manage the packages of many machines. The Devolutions Agent is the device side. It enrolls with DVLS, reports the package inventory from UniGetUI, and runs the install, update and uninstall operations that an administrator pushes from RDM. Install and uninstall scripts make the lab setup fast.
Technical Information
Changes:
device_managementmodule in the agent: package inventory and operations through the UniGetUI IPC API, with a wait until the installed list shows the expected state.package/install:install-agent.ps1/.sh(install and enroll, with a retry until the service is ready),uninstall-agent.ps1/.sh,reinstall-unigetui.ps1, andStart-DevInstallServer.ps1(a development mode that serves local builds).Commits